<?php
class PacketStream extends Connection
{
	const E_PROTOCOL = 2001;
	const E_JSON_PARSE_ERROR = 2002;
	
	private $_currentPacketLen = null;

	public function onAccept() {
		$this->sendPacket(array('now' => time()));
	}

	public function onDataReceived($data) {
		$readed = 0;

		while(strlen($data)) {
			if(is_null($this->_currentPacketLen)) {
				if(strpos($data, "\n") === false)
					return 0;

				if(!preg_match("/^([0-9]{1,6})\r\n/", $data, $m)) {
					Log::warning('E_PROTOCOL', str_replace(array("\r", "\n"), array('\\r', '\\n'), $data));
					$this->_error(self::E_PROTOCOL);
					return 0;
				} else {
					$readed += strlen($m[0]);
					$this->_currentPacketLen = (int)$m[1];
				}
			}

			$data = substr($data, $readed);
			if(strlen($data) >= $this->_currentPacketLen + 2) { // +2 - trailing \r\n
				$packet = substr($data, 0, $this->_currentPacketLen);
				$packet = @json_decode($packet, true);
				if(!$packet) {
					$this->_error(self::E_JSON_PARSE_ERROR);
					return 0;
				}

				$this->onPacketReceived($packet);

				$readed += $this->_currentPacketLen + 2;
				$data = substr($data, $this->_currentPacketLen + 2);
				$this->_currentPacketLen = null;
			} else {
				break;
			}
		}

		return $readed;
	}

	public function onPacketReceived($packet) {
		Log::notice('Received', var_export($packet, true));
	}
	
	public function sendPacket($array) {
		Log::notice('Sending', var_export($array, true));
		$packet = json_encode($array);
		$this->send(sprintf("%u\r\n%s\r\n", strlen($packet), $packet));
	}
}
